/**
 ******************************************************************************
 * @file           : bsp_timer.c
 * @brief          : TIMER Driver Implementation (STM32H7xx)
 ******************************************************************************
 * @attention
 *
 * 定时器驱动程序实现文件
 * 提供软件定时器、延迟、硬件定时器等功能
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "./BSP/TIMER/bsp_timer.h"
#include "./BSP/TIMER/bsp_timer_config.h"

/* Private includes ----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile int32_t g_system_time_ms = 0;                      /*!< 系统运行时间 */
static SoftTimer_t sg_soft_timers[SOFT_TIMER_COUNT];        /*!< 软件定时器数组 */
static volatile uint8_t sg_timer_initialized = 0;          /*!< 初始化标志 */
static volatile TIMER_State_e sg_hw_timer_state = TIMER_STATE_IDLE;  /*!< 硬件定时器状态 */

#ifdef TIMER_USE_TIM2
    static TIM_HandleTypeDef sg_tim_handle = {.Instance = TIM2};
#elif defined(TIMER_USE_TIM3)
    static TIM_HandleTypeDef sg_tim_handle = {.Instance = TIM3};
#elif defined(TIMER_USE_TIM4)
    static TIM_HandleTypeDef sg_tim_handle = {.Instance = TIM4};
#elif defined(TIMER_USE_TIM5)
    static TIM_HandleTypeDef sg_tim_handle = {.Instance = TIM5};
#endif

/* Private function prototypes -----------------------------------------------*/
static void timer_msp_init(void);
static void timer_msp_deinit(void);

/* Private functions ---------------------------------------------------------*/

/**
 * @brief       定时器底层初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        配置GPIO和时钟
 */
static void timer_msp_init(void)
{
#ifdef TIMER_USE_TIM2
    __HAL_RCC_TIM2_CLK_ENABLE();
#elif defined(TIMER_USE_TIM3)
    __HAL_RCC_TIM3_CLK_ENABLE();
#elif defined(TIMER_USE_TIM4)
    __HAL_RCC_TIM4_CLK_ENABLE();
#elif defined(TIMER_USE_TIM5)
    __HAL_RCC_TIM5_CLK_ENABLE();
#endif

    /* 配置中断 */
#ifdef TIMER_USE_TIM2
    HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);
#elif defined(TIMER_USE_TIM3)
    HAL_NVIC_SetPriority(TIM3_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
#elif defined(TIMER_USE_TIM4)
    HAL_NVIC_SetPriority(TIM4_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM4_IRQn);
#elif defined(TIMER_USE_TIM5)
    HAL_NVIC_SetPriority(TIM5_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM5_IRQn);
#endif
}

/**
 * @brief       定时器底层反初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        关闭时钟和中断
 */
static void timer_msp_deinit(void)
{
#ifdef TIMER_USE_TIM2
    __HAL_RCC_TIM2_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM2_IRQn);
#elif defined(TIMER_USE_TIM3)
    __HAL_RCC_TIM3_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM3_IRQn);
#elif defined(TIMER_USE_TIM4)
    __HAL_RCC_TIM4_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM4_IRQn);
#elif defined(TIMER_USE_TIM5)
    __HAL_RCC_TIM5_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM5_IRQn);
#endif
}

/* Public functions ----------------------------------------------------------*/

void timer_init(void)
{
    if (sg_timer_initialized)
    {
        return;
    }

    /* 初始化软件定时器 */
    for (uint8_t i = 0; i < SOFT_TIMER_COUNT; i++)
    {
        sg_soft_timers[i].mode = TIMER_MODE_ONCE;
        sg_soft_timers[i].flag = 0;
        sg_soft_timers[i].count = 0;
        sg_soft_timers[i].preload = 0;
    }

    /* 初始化SysTick */
    HAL_SYSTICK_Config(SystemCoreClock / 1000);

    /* 初始化硬件定时器 */
    timer_msp_init();

    sg_timer_initialized = 1;
    log_i("Timer module initialized");
}

void timer_deinit(void)
{
    if (!sg_timer_initialized)
    {
        return;
    }

    timer_msp_deinit();
    sg_timer_initialized = 0;
    log_i("Timer module deinitialized");
}

void timer_delay_ms(uint32_t ms)
{
    HAL_Delay(ms);
}

void timer_delay_us(uint32_t us)
{
    uint32_t ticks = us * (SystemCoreClock / 1000000);
    uint32_t start = SysTick->VAL;

    while ((start - SysTick->VAL) < ticks)
    {
        ;
    }
}

TIMER_Error_e timer_start(uint8_t id, uint32_t period_ms)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    if (id >= SOFT_TIMER_COUNT)
    {
        log_e("Invalid timer ID: %d", id);
        return TIMER_ERROR_PARAM;
    }

    sg_soft_timers[id].mode = TIMER_MODE_ONCE;
    sg_soft_timers[id].count = period_ms;
    sg_soft_timers[id].preload = 0;
    sg_soft_timers[id].flag = 0;

    log_d("Timer %d started: %u ms", id, period_ms);
    return TIMER_OK;
}

TIMER_Error_e timer_start_auto(uint8_t id, uint32_t period_ms)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    if (id >= SOFT_TIMER_COUNT)
    {
        log_e("Invalid timer ID: %d", id);
        return TIMER_ERROR_PARAM;
    }

    sg_soft_timers[id].mode = TIMER_MODE_AUTO;
    sg_soft_timers[id].count = period_ms;
    sg_soft_timers[id].preload = period_ms;
    sg_soft_timers[id].flag = 0;

    log_d("Timer %d started (auto): %u ms", id, period_ms);
    return TIMER_OK;
}

TIMER_Error_e timer_stop(uint8_t id)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    if (id >= SOFT_TIMER_COUNT)
    {
        log_e("Invalid timer ID: %d", id);
        return TIMER_ERROR_PARAM;
    }

    sg_soft_timers[id].count = 0;
    sg_soft_timers[id].flag = 0;

    log_d("Timer %d stopped", id);
    return TIMER_OK;
}

uint8_t timer_check(uint8_t id)
{
    if (id >= SOFT_TIMER_COUNT)
    {
        return 0;
    }

    if (sg_soft_timers[id].flag)
    {
        sg_soft_timers[id].flag = 0;
        return 1;
    }

    return 0;
}

int32_t timer_get_runtime(void)
{
    return g_system_time_ms;
}

int32_t timer_check_runtime(int32_t last_time)
{
    int32_t current = g_system_time_ms;
    return current - last_time;
}

TIMER_Error_e timer_hw_init(void)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    sg_tim_handle.Init.Prescaler = 0;
    sg_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    sg_tim_handle.Init.Period = 0xFFFF;
    sg_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    sg_tim_handle.Init.RepetitionCounter = 0;
    sg_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    if (HAL_TIM_Base_Init(&sg_tim_handle) != HAL_OK)
    {
        log_e("Hardware timer initialization failed");
        return TIMER_ERROR_HAL;
    }

    sg_hw_timer_state = TIMER_STATE_IDLE;
    log_i("Hardware timer initialized");
    return TIMER_OK;
}

TIMER_Error_e timer_hw_start(void)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    if (HAL_TIM_Base_Start(&sg_tim_handle) != HAL_OK)
    {
        log_e("Hardware timer start failed");
        return TIMER_ERROR_HAL;
    }

    sg_hw_timer_state = TIMER_STATE_RUNNING;
    log_i("Hardware timer started");
    return TIMER_OK;
}

TIMER_Error_e timer_hw_stop(void)
{
    if (!sg_timer_initialized)
    {
        log_e("Timer not initialized");
        return TIMER_ERROR_NOT_INIT;
    }

    if (HAL_TIM_Base_Stop(&sg_tim_handle) != HAL_OK)
    {
        log_e("Hardware timer stop failed");
        return TIMER_ERROR_HAL;
    }

    sg_hw_timer_state = TIMER_STATE_STOPPED;
    log_i("Hardware timer stopped");
    return TIMER_OK;
}

TIMER_State_e timer_hw_get_state(void)
{
    return sg_hw_timer_state;
}

void timer_print_status(void)
{
    const char *state_str[] = {"IDLE", "RUNNING", "STOPPED", "ERROR"};

    log_i("=== Timer Status ===");
    log_i("Initialized: %s", sg_timer_initialized ? "Yes" : "No");
    log_i("System Time: %ld ms", g_system_time_ms);
    log_i("Hardware Timer State: %s", state_str[sg_hw_timer_state]);

    log_i("Software Timers:");
    for (uint8_t i = 0; i < SOFT_TIMER_COUNT; i++)
    {
        if (sg_soft_timers[i].count > 0)
        {
            log_i("  Timer %d: count=%lu, flag=%d", i, sg_soft_timers[i].count, sg_soft_timers[i].flag);
        }
    }
}

/* SysTick中断处理 */
void SysTick_Handler(void)
{
    g_system_time_ms++;

    /* 更新软件定时器 */
    for (uint8_t i = 0; i < SOFT_TIMER_COUNT; i++)
    {
        if (sg_soft_timers[i].count > 0)
        {
            sg_soft_timers[i].count--;

            if (sg_soft_timers[i].count == 0)
            {
                sg_soft_timers[i].flag = 1;

                /* 自动模式：重新加载 */
                if (sg_soft_timers[i].mode == TIMER_MODE_AUTO)
                {
                    sg_soft_timers[i].count = sg_soft_timers[i].preload;
                }
            }
        }
    }
}
